package ndquangr.intern.ringtonemaker;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Vector;

import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.BitmapFactory.Options;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Point;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Bitmap.Config;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.PaintDrawable;
import android.graphics.drawable.ShapeDrawable;
import android.graphics.drawable.shapes.RectShape;
import android.media.AudioFormat;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.os.Environment;
import android.util.TypedValue;
import android.view.Display;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.view.ViewGroup.LayoutParams;
import android.view.ViewTreeObserver;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.SeekBar;
import android.widget.SeekBar.OnSeekBarChangeListener;
import android.widget.Toast;

public class EditAudioActivity extends Activity {
	/** Global variables */
	private Context m_context;
	private Bitmap m_graph;
	private int displayWidth, displayHeight;
	private int file_length;
	private int[] labels;
	private float graph_current_x, graph_current_y;
	private int graph_scrollByX;
	private int graph_realPos, start_realPos, end_realPos;
	private int img_width, img_height;
	
	private int startTime;
	private int endTime;
	private int GRAPH_HEIGHT;
	
	/** Control variables */
	private ImageView img_graph;
	private ImageView img_selection;
	private ImageView img_selection_start;
	private ImageView img_selection_end;
	private ImageView btn_play;
	private ImageView btn_start;
	private ImageView btn_end;
	private ImageView btn_apply;
	private ImageView btn_save;
	private ImageView btn_close;	
	private Drawable slider;
	private FrameLayout flayout;
	short [] data;
	
	// Initialization	
	public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.edit_audio_layout);
        m_context = this;
        	  
        // Get information from intent
        Bundle extras = getIntent().getExtras();
		if (extras != null) {	
			// Get specific songs base on tag
			String path = extras.getString("uri");
			if (path != null && path.endsWith(".wav")) {
				readPCM(path);				
			} else {
				decodeAudio(path);
			}			
			
		}
		
		// Get global values
	    Display display = ((WindowManager)
                getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();

	    displayWidth = display.getWidth();             
	    displayHeight = display.getHeight();
	    graph_realPos = 0; 
	    start_realPos = startTime = 0; 
	    end_realPos = endTime = 50;
	    start_rect = new Rect();
	    end_rect = new Rect();
	    GRAPH_HEIGHT = (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 200, getResources().getDisplayMetrics());
	    // Get all control instances
		getControlInstances();		
		
		// Initialize view for graph of audio data
        initializeGraph();
        
        // Add action listener for controls
        addActionListener();       
        
	}

	/*
	 * Add action listeners to controls
	 */
	private void addActionListener() {
		img_graph.setOnTouchListener(graphTouchEvent);
		img_selection_start.setOnTouchListener(startSelectionTouchEvent);
		img_selection_end.setOnTouchListener(endSelectionTouchEvent);
	}

	/*
	 * Initialize audio data graph
	 */
	private void initializeGraph() {		
		m_graph = Bitmap.createBitmap(data.length/100, (int)Math.floor(GRAPH_HEIGHT), Bitmap.Config.ARGB_8888);
        createGraph(m_graph);

		//m_graph = BitmapFactory.decodeResource(getResources(), R.drawable.landscape);
		img_width = m_graph.getWidth();
		img_height = m_graph.getHeight();
		
		// Set up ImageView for graph
		/** Set matrix for image view */
		/*
        Matrix matrix = new Matrix();
        matrix.postTranslate(0, img_height/2);
        img_graph.setImageMatrix(matrix);
        */
		
        img_graph.setImageBitmap(m_graph); 
        
        slider = getResources().getDrawable(R.drawable.slider);
        
        img_selection_start.setImageDrawable(slider);
        img_selection_end.setImageDrawable(slider);
        img_selection_start.scrollTo(-startTime + slider.getIntrinsicWidth()/2, 0);
        img_selection_end.scrollTo(-endTime + slider.getIntrinsicWidth()/2, 0);
        
        drawSelectionRegion(startTime, endTime);
	}

	/*
	 * Generate graph (wave form) from audio data
	 */
	private void createGraph(Bitmap bitmap) {
		// TODO Auto-generated method stub
		Canvas canvas = new Canvas(bitmap);
        
        final int color = Color.BLUE; 
        final Paint paint = new Paint();
        paint.setColor(color);
        
        float cur_point_x, cur_point_y;
        float next_point_x, next_point_y;

        int i = 1;
        next_point_x = 0;
        next_point_y = -data[0]/20 + GRAPH_HEIGHT/2;
        while(i<data.length) {
        	cur_point_x = next_point_x;
        	cur_point_y = next_point_y;
        	next_point_x = i/100;
            next_point_y = -data[i]/20 + GRAPH_HEIGHT/2;
            canvas.drawLines(new float [] {cur_point_x, cur_point_y, next_point_x, 
            		next_point_y}, paint);
            i++;
        }
        
	}

	/*
	 * Draw selection region
	 */
	private void drawSelectionRegion(int start, int end) {
		// TODO Auto-generated method stub
		if (end < 0 || start > displayWidth) {
			img_selection.setImageResource(0);
		} else {
			if (start < 0) {
				start = 0;
			} else if (end > displayWidth) {
				end = displayWidth;
			}
			Rect r = new Rect(0, 0, start, img_height);
			Paint paint = new Paint();
			paint.setStyle(Paint.Style.STROKE);
			paint.setColor(Color.BLUE);
			Canvas canvas = new Canvas();
			canvas.drawRect(r, paint);
			Rect r2 = new Rect(start, 0, end, img_height);
			
			paint.setColor(Color.RED);
			canvas.drawRect(r2, paint);
			Bitmap b = Bitmap.createBitmap(end, img_height, Bitmap.Config.ARGB_8888);	
			//canvas.drawb
			
			//draw.setAlpha(50);
			FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(end, img_height);
			params.setMargins(start, 0, 0, 0);
			
			img_selection.setLayoutParams(params);			
			//img_selection.setPadding(start, 20, 20, 20);
			//img_selection.setAdjustViewBounds(false);
			img_selection.draw(canvas);
		}
		
		img_selection.refreshDrawableState();
		//img_selection.invalidate();
	}

	/*
	 * Get view control instances
	 */
	private void getControlInstances() {
		img_graph = (ImageView) findViewById(R.id.img_audioEdit_graph);
		img_selection = (ImageView) findViewById(R.id.img_audioEdit_selection);
		img_selection_start = (ImageView) findViewById(R.id.img_audioEdit_startTime);
		img_selection_end = (ImageView) findViewById(R.id.img_audioEdit_endTime);
		img_height = img_graph.getLayoutParams().height;	
		flayout = (FrameLayout) findViewById(R.id.fl_audioEdit);
		/*
		ViewTreeObserver vto = img_graph.getViewTreeObserver();
		vto.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
		    public boolean onPreDraw() {
		        img_height = img_graph.getMeasuredHeight();		        
		        return true;
		    }
		});
	*/
	}

	/*
	 * Decode Mp3 files
	 */
	private void decodeAudio(String path) {
		// TODO Auto-generated method stub
		
	}

	/*
	 * Read wav file
	 */
	private void readPCM(String path) {
		// TODO Auto-generated method stub
		WavIO waveFile = new WavIO(path);
		String sbody = "";
		if (waveFile.read()){
			data = WavIO.byteArrayToFloat(waveFile.myData);
			// Write data to text file
			/**
			try
		    {
		        File root = new File(Environment.getExternalStorageDirectory(), "My tones");
		        if (!root.exists()) {
		            root.mkdirs();
		        }
		        File gpxfile = new File(root, "data.txt");
		        FileWriter writer = new FileWriter(gpxfile);
		        for (int i = 0; i< data.length; i++) {
		        	writer.append(data[i] + " ");
				}

		        writer.flush();
		        writer.close();
		        Toast.makeText(this, "Saved", Toast.LENGTH_SHORT).show();
		    }
		    catch(IOException e)
		    {
		         e.printStackTrace();
		    }
			*/
		}
		
	}
	
	/*
	 * Action listeners for images
	 */
	private int real_scroll;
	// Action listener for touch event on graph
	private OnTouchListener graphTouchEvent = new OnTouchListener() {
		
		@Override
		public boolean onTouch(View v, MotionEvent event) {
			float curX, curY;
			
            switch (event.getAction()) {
            	
                case MotionEvent.ACTION_DOWN:
                    graph_current_x = event.getX();
                    graph_current_y = event.getY();
                    break;
                case MotionEvent.ACTION_MOVE:
                    curX = event.getX();
                    curY = event.getY();
                    graph_scrollByX = (int) (graph_current_x - curX);
                    if ((graph_realPos + graph_scrollByX) < 0) {
                    	real_scroll = -graph_realPos;
                    	graph_realPos = 0;
                    }
                    else if ((graph_realPos + graph_scrollByX) > (img_width - displayWidth)) {
                    	real_scroll = img_width - displayWidth - graph_realPos;
                    	graph_realPos = img_width - displayWidth;
                    } else {  
                    	real_scroll = graph_scrollByX;                    	
                    	graph_realPos+= graph_scrollByX;
                    }

                    // Scroll graph and also the sliders
                	img_graph.scrollBy(real_scroll, 0);
                	img_selection_start.scrollBy(real_scroll, 0);
                	img_selection_end.scrollBy(real_scroll, 0);
                	prepareRedrawSelectionRegion();
                	
                    graph_current_x = curX;
                	graph_current_y = curY;
                    break;
                    
                case MotionEvent.ACTION_UP:
                	curX = event.getX();
                    curY = event.getY();
                    graph_scrollByX = (int) (graph_current_x - curX);
                    if ((graph_realPos + graph_scrollByX) < 0) {
                    	real_scroll = -graph_realPos;
                    	graph_realPos = 0;
                    }
                    else if ((graph_realPos + graph_scrollByX) > (img_width - displayWidth)) {
                    	real_scroll = img_width - displayWidth - graph_realPos;
                    	graph_realPos = img_width - displayWidth;
                    } else {  
                    	real_scroll = graph_scrollByX;                    	
                    	graph_realPos+= graph_scrollByX;
                    }

                    // Scroll graph and also the sliders
                	img_graph.scrollBy(real_scroll, 0);
                	img_selection_start.scrollBy(real_scroll, 0);
                	img_selection_end.scrollBy(real_scroll, 0);
                	prepareRedrawSelectionRegion();
                    break;
            }

            return true;
		}
	};
	
	float start_current_x, start_current_y;
	int start_scroll_by_x;
	Rect start_rect, end_rect;
	// Action listener for touch event on graph
	private OnTouchListener startSelectionTouchEvent = new OnTouchListener() {
		
		@Override
		public boolean onTouch(View v, MotionEvent event) {
			float curX, curY;
			
            switch (event.getAction()) {
            	
                case MotionEvent.ACTION_DOWN:
                	start_current_x = event.getX();
                	start_current_y = event.getY();
                    break;
                case MotionEvent.ACTION_MOVE:
                    curX = event.getX();
                    curY = event.getY();
                    start_scroll_by_x = (int) (start_current_x - curX);
                    start_realPos -= start_scroll_by_x;
                    end_realPos -= start_scroll_by_x;
                    
                    // Scroll two sliders
                    img_selection_start.scrollBy(start_scroll_by_x, 0);
                    img_selection_end.scrollBy(start_scroll_by_x, 0);                
                    prepareRedrawSelectionRegion();
                    
                    start_current_x = curX;
                    start_current_y = curY;
                    break;
                    
                case MotionEvent.ACTION_UP:
                	curX = event.getX();
                    curY = event.getY();
                    start_scroll_by_x = (int) (start_current_x - curX);
                    start_realPos -= start_scroll_by_x;
                    end_realPos -= start_scroll_by_x;
                    
                    // Scroll two sliders
                    img_selection_start.scrollBy(start_scroll_by_x, 0);
                    img_selection_end.scrollBy(start_scroll_by_x, 0);
                    prepareRedrawSelectionRegion();
                    
                    break;
            }

            return true;
		}
	};
	
	float end_current_x, end_current_y;
	int end_scroll_by_x;
	// Action listener for touch event on graph
	private OnTouchListener endSelectionTouchEvent = new OnTouchListener() {
		
		@Override
		public boolean onTouch(View v, MotionEvent event) {
			float curX, curY;
			
            switch (event.getAction()) {
            	
                case MotionEvent.ACTION_DOWN:
                	end_current_x = event.getX();
                	end_current_y = event.getY();
                    break;
                case MotionEvent.ACTION_MOVE:
                    curX = event.getX();
                    curY = event.getY();
                    end_scroll_by_x = (int) (end_current_x - curX);
                   
                    end_realPos -= end_scroll_by_x;
                    
                    img_selection_end.scrollBy(end_scroll_by_x, 0);
                    prepareRedrawSelectionRegion();
                    end_current_x = curX;
                    end_current_y = curY;
                    break;
                    
                case MotionEvent.ACTION_UP:
                	curX = event.getX();
                    curY = event.getY();
                    end_scroll_by_x = (int) (end_current_x - curX);
                    end_realPos -= end_scroll_by_x;
                    
                    img_selection_end.scrollBy(end_scroll_by_x, 0);
                    prepareRedrawSelectionRegion();
                    
                    break;
            }

            return true;
		}
		
	};
	
	private void prepareRedrawSelectionRegion() {
		//img_selection_start.getDrawingRect(start_rect);
		//img_selection_end.getDrawingRect(end_rect);
		//drawSelectionRegion(start_rect.left, end_rect.left);
		drawSelectionRegion(start_realPos - graph_realPos, end_realPos - graph_realPos);
	}
}
